﻿/*************************************************************************************

- CLR版本：        4.0.30319.42000
- 类 名 称：       MVSCamera
- 机器名称：       YTE
- 命名空间：       LD.Vision.Camera
- 文 件 名：       MVSCamera
- 创建时间：       2022/7/13 16:58:24
- 作    者：       YTE
- 说   明：
- 修改时间：
- 修 改 人：
  *************************************************************************************/

using HalconDotNet;
using MvCamCtrl.NET;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using 右下角弹窗.DiagShow;

namespace LD.Vision
{
    /// <summary>
    /// 海康相机
    /// </summary>
    [Camera(Name = "海康相机", Brand = CameraType.海康)]
    public class CameraHik : AbsCamera, IDisposable
    {
        [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
        public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
        private MyCamera.MV_CC_DEVICE_INFO_LIST m_pDeviceList;
        private MyCamera m_pMyCamera;
        private bool m_bGrabbing;
        private MyCamera.MVCC_FLOATVALUE stParam;
        private MyCamera.cbOutputExdelegate cbImage;
        private MyCamera.MV_FRAME_OUT_INFO_EX m_stFrameInfo;
        public CameraHik()
        {
            m_pDeviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
            m_pMyCamera = new MyCamera();
            m_bGrabbing = false;
            stParam = new MyCamera.MVCC_FLOATVALUE();
            cbImage = new MyCamera.cbOutputExdelegate(ImageCallBack);
            m_stFrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX();
        }
        public CameraHik(string name) : this()
        {
            Name = name;
        }
        public override List<string> GetCamera()
        {
            return DeviceListAcq();
        }

        public override void Open(int index)
        {
            if (m_pDeviceList.pDeviceInfo == null || m_pDeviceList.pDeviceInfo.Count() == 0)
                GetCamera();
            int nRet = -1;
            //先关闭
            m_pMyCamera.MV_CC_StopGrabbing_NET();
            m_pMyCamera.MV_CC_CloseDevice_NET();

            //ch:获取选择的设备信息 | en:Get selected device information
            MyCamera.MV_CC_DEVICE_INFO device =
                (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[index],
                                                              typeof(MyCamera.MV_CC_DEVICE_INFO));

            nRet = m_pMyCamera.MV_CC_CreateDevice_NET(ref device);
            if (MyCamera.MV_OK != nRet)
            {
                return;
            }

            // ch:打开设备 | en:Open device
            nRet = m_pMyCamera.MV_CC_OpenDevice_NET();
            if (MyCamera.MV_OK != nRet)
            {
                Dialog dialog = new Dialog();
                dialog.Warning("打开失败");
                return;
            }

            // ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
            if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
            {
                int nPacketSize = m_pMyCamera.MV_CC_GetOptimalPacketSize_NET();
                if (nPacketSize > 0)
                {
                    nRet = m_pMyCamera.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize);
                }
            }

            // ch:设置触发模式为off || en:set trigger mode as off
            m_pMyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF);
            m_pMyCamera.MV_CC_RegisterImageCallBackEx_NET(cbImage, (IntPtr)index);

        }
        public override void Close()
        {
            if (m_bGrabbing)
            {
                m_bGrabbing = false;
                // ch:停止抓图 || en:Stop grab image
                m_pMyCamera.MV_CC_StopGrabbing_NET();
            }
            m_bGrabbing = false;

            m_pMyCamera.MV_CC_StopGrabbing_NET();
            //HWindow.HobjectToHimage(null);
            // ch:关闭设备 || en: Close device
            m_pMyCamera.MV_CC_CloseDevice_NET();

            m_pMyCamera.MV_CC_DestroyDevice_NET();
        }
        public override void StartGrab()
        {
            // ch:开启抓图 | en:start grab
            //int nRet = m_pMyCamera.MV_CC_StartGrabbing_NET();
            //if (MyCamera.MV_OK != nRet)
            //{
            //    Dialog dialog = new Dialog();
            //    dialog.Warning("采集失败");
            //    return;
            //}
            //m_bGrabbing = true;

            //Thread hReceiveImageThreadHandle = new Thread(ReceiveImageWorkThread);
            //hReceiveImageThreadHandle.Start(m_pMyCamera);


            m_stFrameInfo.nFrameLen = 0;//取流之前先清除帧长度
            m_stFrameInfo.enPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Undefined;
            int nRet = m_pMyCamera.MV_CC_StartGrabbing_NET();
            if (MyCamera.MV_OK != nRet)
            {
                Dialog dialog = new Dialog();
                dialog.Warning("采集失败");
                return;
            }
        }
        public override void StopGrab()
        {
            // ch:停止抓图 || en:Stop grab image
            int nRet = m_pMyCamera.MV_CC_StopGrabbing_NET();
            if (nRet != MyCamera.MV_OK)
            {
                Dialog dialog = new Dialog();
                dialog.Warning("停止失败");
            }
            m_bGrabbing = false;
        }

        public override bool Trigger()
        {
            // ch: 触发命令 || en: Trigger command
            resetEvent.Reset();

            int nRet = m_pMyCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");
            if (MyCamera.MV_OK != nRet)
            {
                Dialog dialog = new Dialog();
                dialog.Warning("触发失败");
                return false;
            }
            if (resetEvent.WaitOne(1000))
                return true;
            else
                return false;
        }
        /// <summary>
        /// 连续模式
        /// </summary>
        private bool continuesMode = false;
        public override bool ContinuesMode
        {
            get
            {
                return continuesMode;
            }
            set
            {
                if (value)
                {
                    m_pMyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0);
                    m_pMyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF);
                    continuesMode = value;
                }
            }
        }
        /// <summary>
        /// 触发模式
        /// </summary>
        private bool triggerMode = false;
        public override bool TriggerMode
        {
            get
            {
                return triggerMode;
            }
            set
            {
                if (value)
                {
                    m_pMyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
                    m_pMyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
                    triggerMode = value;
                }
            }
        }
        private List<string> DeviceListAcq()
        {
            List<string> camers = new List<string>();
            int nRet;
            // ch:创建设备列表 || en: Create device list
            System.GC.Collect();
            nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList);
            if (MyCamera.MV_OK != nRet)
            {
                Dialog dialog = new Dialog();
                dialog.Warning("相机获取失败");
                return camers;
            }

            // ch:在窗体列表中显示设备名 || Display the device'name on window's list
            for (int i = 0; i < m_pDeviceList.nDeviceNum; i++)
            {
                MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
                if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
                {
                    IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0);
                    MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
                    if (gigeInfo.chUserDefinedName != "")
                    {
                        //camers.Add("GigE:【" + gigeInfo.chUserDefinedName + "】(" + gigeInfo.chSerialNumber + ")");
                        camers.Add(gigeInfo.chUserDefinedName);
                    }
                    else
                    {
                        //camers.Add("GigE:【" + gigeInfo.chManufacturerName + "】" + gigeInfo.chModelName + "(" + gigeInfo.chSerialNumber + ")");
                        camers.Add(gigeInfo.chManufacturerName);
                    }
                }
                else if (device.nTLayerType == MyCamera.MV_USB_DEVICE)
                {
                    IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stUsb3VInfo, 0);
                    MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_USB3_DEVICE_INFO));
                    if (usbInfo.chUserDefinedName != "")
                    {
                        //camers.Add("USB:【" + usbInfo.chUserDefinedName + "】(" + usbInfo.chSerialNumber + ")");
                        camers.Add(usbInfo.chUserDefinedName);
                    }
                    else
                    {
                        //camers.Add("USB:【" + usbInfo.chManufacturerName + "】" + usbInfo.chModelName + "(" + usbInfo.chSerialNumber + ")");
                        camers.Add(usbInfo.chManufacturerName);
                    }
                }
            }
            return camers;
        }
        // ch:取流回调函数 | en:Aquisition Callback Function
        private void ImageCallBack(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser)
        {
            int m_nSaveImageBufSize = 0;
            IntPtr m_pSaveImageBuf = IntPtr.Zero;
            HObject Hobj = new HObject();

            if (m_pSaveImageBuf == IntPtr.Zero || pFrameInfo.nFrameLen > m_nSaveImageBufSize)
            {
                if (m_pSaveImageBuf != IntPtr.Zero)
                {
                    Marshal.Release(m_pSaveImageBuf);
                    m_pSaveImageBuf = IntPtr.Zero;
                }

                m_pSaveImageBuf = Marshal.AllocHGlobal((Int32)pFrameInfo.nFrameLen);
                if (m_pSaveImageBuf == IntPtr.Zero)
                {
                    return;
                }
                m_nSaveImageBufSize = (int)pFrameInfo.nFrameLen;
            }

            m_stFrameInfo = pFrameInfo;
            CopyMemory(m_pSaveImageBuf, pData, pFrameInfo.nFrameLen);

            MyCamera.MV_DISPLAY_FRAME_INFO stDisplayInfo = new MyCamera.MV_DISPLAY_FRAME_INFO();
            //stDisplayInfo.hWnd = HWindow.HWindowHalconID;
            stDisplayInfo.pData = pData;
            stDisplayInfo.nDataLen = pFrameInfo.nFrameLen;
            stDisplayInfo.nWidth = pFrameInfo.nWidth;
            stDisplayInfo.nHeight = pFrameInfo.nHeight;
            stDisplayInfo.enPixelType = pFrameInfo.enPixelType;

            m_pMyCamera.MV_CC_DisplayOneFrame_NET(ref stDisplayInfo);

            HOperatorSet.GenImage1Extern(out Hobj, "byte", pFrameInfo.nWidth, pFrameInfo.nHeight, pData, IntPtr.Zero);


            resetEvent.Set();
            //Image = new HImage(Image);
            //HalconDisplay(HWindow.HWindowHalconID, Hobj, stDisplayInfo.nHeight, stDisplayInfo.nWidth);

            //save image
            if (triggerMode && IsSaveImage)
            {
                SaveImage();
            }
            Hobj.Dispose();

        }
        private bool IsColorPixelFormat(MyCamera.MvGvspPixelType enType)
        {
            switch (enType)
            {
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGBA8_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGRA8_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_YUYV_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12_Packed:
                    return true;
                default:
                    return false;
            }
        }
        private bool IsMonoPixelFormat(MyCamera.MvGvspPixelType enType)
        {
            switch (enType)
            {
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12_Packed:
                    return true;
                default:
                    return false;
            }
        }
        public void ReceiveImageWorkThread(object obj)
        {
            int nRet = MyCamera.MV_OK;
            MyCamera device = obj as MyCamera;
            MyCamera.MV_FRAME_OUT stFrameOut = new MyCamera.MV_FRAME_OUT();

            IntPtr pImageBuf = IntPtr.Zero;
            int nImageBufSize = 0;

            HObject Hobj = new HObject();
            IntPtr pTemp = IntPtr.Zero;

            while (m_bGrabbing)
            {
                nRet = device.MV_CC_GetImageBuffer_NET(ref stFrameOut, 100);
                if (MyCamera.MV_OK == nRet)
                {
                    if (IsColorPixelFormat(stFrameOut.stFrameInfo.enPixelType))
                    {
                        if (stFrameOut.stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed)
                        {
                            pTemp = stFrameOut.pBufAddr;
                        }
                        else
                        {
                            if (IntPtr.Zero == pImageBuf || nImageBufSize < (stFrameOut.stFrameInfo.nWidth * stFrameOut.stFrameInfo.nHeight * 3))
                            {
                                if (pImageBuf != IntPtr.Zero)
                                {
                                    Marshal.FreeHGlobal(pImageBuf);
                                    pImageBuf = IntPtr.Zero;
                                }

                                pImageBuf = Marshal.AllocHGlobal((int)stFrameOut.stFrameInfo.nWidth * stFrameOut.stFrameInfo.nHeight * 3);
                                if (IntPtr.Zero == pImageBuf)
                                {
                                    break;
                                }
                                nImageBufSize = stFrameOut.stFrameInfo.nWidth * stFrameOut.stFrameInfo.nHeight * 3;
                            }

                            MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();

                            stPixelConvertParam.pSrcData = stFrameOut.pBufAddr;//源数据
                            stPixelConvertParam.nWidth = stFrameOut.stFrameInfo.nWidth;//图像宽度
                            stPixelConvertParam.nHeight = stFrameOut.stFrameInfo.nHeight;//图像高度
                            stPixelConvertParam.enSrcPixelType = stFrameOut.stFrameInfo.enPixelType;//源数据的格式
                            stPixelConvertParam.nSrcDataLen = stFrameOut.stFrameInfo.nFrameLen;

                            stPixelConvertParam.nDstBufferSize = (uint)nImageBufSize;
                            stPixelConvertParam.pDstBuffer = pImageBuf;//转换后的数据
                            stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed;
                            nRet = device.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换
                            if (MyCamera.MV_OK != nRet)
                            {
                                break;
                            }
                            pTemp = pImageBuf;
                        }

                        try
                        {
                            HOperatorSet.GenImageInterleaved(out Hobj, (HTuple)pTemp, (HTuple)"rgb", (HTuple)stFrameOut.stFrameInfo.nWidth, (HTuple)stFrameOut.stFrameInfo.nHeight, -1, "byte", 0, 0, 0, 0, -1, 0);
                        }
                        catch (HalconException hex)
                        {
                            Console.WriteLine(hex.Message);
                            throw hex;
                        }
                    }
                    else if (IsMonoPixelFormat(stFrameOut.stFrameInfo.enPixelType))
                    {
                        if (stFrameOut.stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
                        {
                            pTemp = stFrameOut.pBufAddr;
                        }
                        else
                        {
                            if (IntPtr.Zero == pImageBuf || nImageBufSize < (stFrameOut.stFrameInfo.nWidth * stFrameOut.stFrameInfo.nHeight))
                            {
                                if (pImageBuf != IntPtr.Zero)
                                {
                                    Marshal.FreeHGlobal(pImageBuf);
                                    pImageBuf = IntPtr.Zero;
                                }

                                pImageBuf = Marshal.AllocHGlobal((int)stFrameOut.stFrameInfo.nWidth * stFrameOut.stFrameInfo.nHeight);
                                if (IntPtr.Zero == pImageBuf)
                                {
                                    break;
                                }
                                nImageBufSize = stFrameOut.stFrameInfo.nWidth * stFrameOut.stFrameInfo.nHeight;
                            }

                            MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();

                            stPixelConvertParam.pSrcData = stFrameOut.pBufAddr;//源数据
                            stPixelConvertParam.nWidth = stFrameOut.stFrameInfo.nWidth;//图像宽度
                            stPixelConvertParam.nHeight = stFrameOut.stFrameInfo.nHeight;//图像高度
                            stPixelConvertParam.enSrcPixelType = stFrameOut.stFrameInfo.enPixelType;//源数据的格式
                            stPixelConvertParam.nSrcDataLen = stFrameOut.stFrameInfo.nFrameLen;

                            stPixelConvertParam.nDstBufferSize = (uint)nImageBufSize;
                            stPixelConvertParam.pDstBuffer = pImageBuf;//转换后的数据
                            stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8;
                            nRet = device.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换
                            if (MyCamera.MV_OK != nRet)
                            {
                                break;
                            }
                            pTemp = pImageBuf;
                        }
                        try
                        {
                            HOperatorSet.GenImage1Extern(out Hobj, "byte", stFrameOut.stFrameInfo.nWidth, stFrameOut.stFrameInfo.nHeight, pTemp, IntPtr.Zero);
                        }
                        catch (System.Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                            break;
                        }
                    }
                    else
                    {
                        device.MV_CC_FreeImageBuffer_NET(ref stFrameOut);
                        continue;
                    }
                    //HalconDisplay(HWindow.HWindowHalconID, Hobj, stFrameOut.stFrameInfo.nHeight, stFrameOut.stFrameInfo.nWidth);

                    device.MV_CC_FreeImageBuffer_NET(ref stFrameOut);
                }
                else
                {
                    continue;
                }
            }

            if (pImageBuf != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(pImageBuf);
                pImageBuf = IntPtr.Zero;
            }
        }
        public void HalconDisplay(HTuple hWindow, HObject Hobj, HTuple hHeight, HTuple hWidth)
        {
            // ch: 显示 || display
            //try
            //{
            //    HOperatorSet.SetPart(hWindow, 0, 0, hHeight - 1, hWidth - 1);// ch: 使图像显示适应窗口大小 || en: Make the image adapt the window size
            //}
            //catch (Exception ex)
            //{
            //    return;
            //}
            if (hWindow == null || Hobj == null)
            {
                Console.WriteLine("HWindowOr图片为Null");
                return;
            }
            try
            {
                //HWindow.HobjectToHimage(Hobj);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public override float Exposure
        {
            get
            {
                //MyCamera.MVCC_FLOATVALUE stParam = new MyCamera.MVCC_FLOATVALUE();
                int nRet = m_pMyCamera.MV_CC_GetFloatValue_NET("ExposureTime", ref stParam);
                if (MyCamera.MV_OK == nRet)
                {
                    return stParam.fCurValue;
                }
                return 0;
            }
            set
            {
                m_pMyCamera.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
                int nRet = m_pMyCamera.MV_CC_SetFloatValue_NET("ExposureTime", value);
                if (nRet != MyCamera.MV_OK)
                {
                    Console.WriteLine("Write Fail");
                }
            }
        }

        public override float Gain
        {
            get
            {
                //MyCamera.MVCC_FLOATVALUE stParam = new MyCamera.MVCC_FLOATVALUE();
                int nRet = m_pMyCamera.MV_CC_GetFloatValue_NET("Gain", ref stParam);
                if (MyCamera.MV_OK == nRet)
                {
                    return stParam.fCurValue;
                }
                return 0;
            }
            set
            {
                m_pMyCamera.MV_CC_SetEnumValue_NET("GainAuto", 0);
                int nRet = m_pMyCamera.MV_CC_SetFloatValue_NET("Gain", value);
                if (nRet != MyCamera.MV_OK)
                {
                    Console.WriteLine("Write Fail");
                }
            }
        }

        public override float FrameRate
        {
            get
            {
                int nRet = m_pMyCamera.MV_CC_GetFloatValue_NET("AcquisitionFrameRate", ref stParam);
                if (MyCamera.MV_OK == nRet)
                {
                    return stParam.fCurValue;
                }
                return 0;
            }
            set
            {
                int nRet = m_pMyCamera.MV_CC_SetFloatValue_NET("AcquisitionFrameRate", value);
                if (nRet != MyCamera.MV_OK)
                {
                    Console.WriteLine("Write Fail");
                }
            }
        }

        public override float Gamma
        {
            get
            {
                int nRet = m_pMyCamera.MV_CC_GetFloatValue_NET("Gamma", ref stParam);
                if (MyCamera.MV_OK == nRet)
                {
                    return stParam.fCurValue;
                }
                return 0;
            }
            set
            {
                int nRet = m_pMyCamera.MV_CC_SetFloatValue_NET("Gamma", value);
                if (nRet != MyCamera.MV_OK)
                {
                    Console.WriteLine("Write Fail");
                }
            }

        }
    }
}
